#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>

int main(int argc, char *argv[]) {
  int f,start,stop,begin;
  unsigned int c;

  int *map;
  struct stat st;
  int size;

  FILE *fpread;
  int   fpidx;

  char file[255];
 
  if (argc != 3) {
    printf("USAGE = gl fichier ligne\n");
    exit(1);
  }
  strcpy(file,argv[1]); /*Copying name of file for concat */
  
  fpread = fopen(file,"r");
  if (fpread == NULL) {
    printf("Error openning reading file : %s\n",argv[1]);
    abort();
  }
  /* Get IDX size */
  if (stat(strcat(file,".idx"), &st) < 0) {
    perror("Erreur lors de du stat du fichier index");
    abort();
  }
  size = st.st_size;
  /* Openning idx file in read only */
  fpidx = open(file,O_RDONLY);
  if (fpidx == -1) {
    printf("Error openning writing file : %s\n",file);
    abort();
  }
  
  /* Déplacement à l'emplacement correspondant à la ligne */
  start=atoi(argv[2]);
  printf("Lecture du fichier .idx a l'octet %i\n",start);

  /* On lit le fichier à l'aide de mmap */
  /* sysconf(_SC_PAGESIZE) est utilisé pour avoir la taille de la page
     en effet l'ofset doit être un multiple de cette taille */
  map = mmap(0,size,PROT_READ, MAP_SHARED, fpidx, 0);
  if (map == MAP_FAILED) {
    perror("Erreurr lors du mmap du fichier");
    abort();
  }
  begin = map[start];
  stop = map[start+1];

  printf("On commence la lecture a l'octet %i et on terminera a %i\n",begin,stop);
  f=fseek(fpread,begin,SEEK_SET);
  if (f != 0) { printf("Erreur lors du fseek"); exit(1); }

  while ((c = fgetc(fpread)) != EOF) {
     if (begin == stop) {
       /* If begin == stop, we have read the line */
       break;
     }
     if (putchar(c) == EOF) { /* Printing line */
        printf("Erreur lors de l'écriture");
        abort();
     }
     begin++; 
   }


  close(fpidx);
  fclose(fpread);
  return EXIT_SUCCESS;
}
